package main

import (
	"context"
	"fmt"
	"github.com/golang/protobuf/ptypes/timestamp"
	"google.golang.org/grpc"
	"io"

	//"google/protobuf/timestamp.proto"
	"grpcClient/helper"
	"grpcClient/services"
	"log"
	"time"
)

const (
	// Address gRPC服务地址
	Address = "127.0.0.1:8888"
)

func main() {
	// TLS连接
	//从证书相关文件中读取和解析信息，得到证书公钥、密钥对
	conn, err := grpc.Dial(Address, grpc.WithTransportCredentials(helper.GetClientCreds())) //连接服务端
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	ctx := context.Background()
	prodClient := services.NewProdServiceClient(conn)                                                                //商品服务                                                           //初始化客户端
	prodRes, err := prodClient.GetProdStock(ctx, &services.ProdRequest{ProdId: 12, ProdAreas: services.ProdAreas_B}) //调用方法
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("grpcClient getProdStock is %d\n", prodRes.ProdStock)

	response, err := prodClient.GetProdStocks(ctx, &services.QuerySize{Size: 5})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("grpcClient getProdStock is %d\n", response.ProdRes[1].ProdStock)
	fmt.Println(response.ProdRes)

	res, err := prodClient.GetProdInfo(ctx, &services.ProdRequest{ProdId: 12})
	fmt.Println(res)

	tm := timestamp.Timestamp{Seconds: time.Now().Unix()}
	orderClient := services.NewOrderServiceClient(conn) // 订单服务
	res1, _ := orderClient.NewOrder(ctx, &services.OrderMainModel{
		OrderId:    1,
		OrderNo:    "12345",
		OrderMoney: 200,
		OrderTime:  &tm,
	})
	fmt.Println("newOrder---", res1)
	//传统批量方式
	userScoreClient := services.NewUserScoreServiceClient(conn) // 用户积分查询服务
	userScoreReq := services.UserScoreRequest{}
	userScoreReq.Users = make([]*services.UserInfo, 0, 5)
	for i := 1; i <= 5; i++ {
		userScoreReq.Users = append(userScoreReq.Users, &services.UserInfo{UserId: int32(i)})
	}
	userScoreRes, _ := userScoreClient.GetUserScore(ctx, &userScoreReq) // 等待获取所有的数据
	fmt.Println("userScore---", userScoreRes.Users)

	// 服务端流
	userScoreClient = services.NewUserScoreServiceClient(conn)
	userScoreReq = services.UserScoreRequest{}
	userScoreReq.Users = make([]*services.UserInfo, 0, 5)
	for i := 6; i <= 10; i++ {
		userScoreReq.Users = append(userScoreReq.Users, &services.UserInfo{UserId: int32(i)})
	}
	userScoreResByServerStream, err := userScoreClient.GetUserScoreByServerStream(ctx, &userScoreReq)
	if err != nil {
		log.Fatal(err)
	}
	for {
		streamRes, err := userScoreResByServerStream.Recv()
		if err == io.EOF { //说明接收完了
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(streamRes.Users) //获取到数据，开启协程去处理其他事情
	}
	// 客户端流
	userScoreClient = services.NewUserScoreServiceClient(conn)
	userScoreResByClientStream, err := userScoreClient.GetUserScoreByClientStream(ctx)
	if err != nil {
		log.Fatal(err)
	}
	var j int32 = 11
	for i := 1; i <= 3; i++ {
		userScoreReq = services.UserScoreRequest{}
		userScoreReq.Users = make([]*services.UserInfo, 0)
		MaxNum := j + 5
		for ; j <= MaxNum; j++ {
			userScoreReq.Users = append(userScoreReq.Users, &services.UserInfo{UserId: j})
		}
		err = userScoreResByClientStream.Send(&userScoreReq)
		if err != nil {
			log.Println(err)
		}
	}
	streamRes1, err := userScoreResByClientStream.CloseAndRecv()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(streamRes1.Users)

	//双向流模式
	userScoreClient = services.NewUserScoreServiceClient(conn)
	userScoreResByTwoStream, err := userScoreClient.GetUserScoreByTwoStream(ctx)
	if err != nil {
		log.Fatal(err)
	}
	var k int32 = 11
	for i := 1; i <= 3; i++ {
		userScoreReq = services.UserScoreRequest{}
		userScoreReq.Users = make([]*services.UserInfo, 0)
		MaxNum := k + 5
		for ; k < MaxNum; k++ {
			userScoreReq.Users = append(userScoreReq.Users, &services.UserInfo{UserId: k})
		}
		err := userScoreResByTwoStream.Send(&userScoreReq)
		if err != nil {
			log.Println(err)
		}
		twoStreamRes, err := userScoreResByTwoStream.Recv()
		if err == io.EOF {
			log.Println(err)
		}
		if err != nil {
			log.Println(err)
		}
		fmt.Println("twoStreamRes", twoStreamRes.Users)
	}
}
